﻿using Bentley.GeometryNET;
using CheccCoverplateCulvertAssemble.Conmmon;
using CheccCoverplateCulvertAssemble.Entity;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Text.RegularExpressions;

namespace CheccCoverplateCulvertAssemble.Rebar;

public class Rebar_135Degrees : RebarBase
{
    private readonly double m_lengthOfHook = 0.0;

    public Rebar_135Degrees(ConstructingEntity constructingEntity, string rebarGroupNumber, double diameter, string grades, RebarType rebarType, CurveVector baseLine, double lengthOfHook, double hookDiameter = 0.0, double startRotationAngle = 0, double endRotationAngle = 0)
        : base(constructingEntity, rebarGroupNumber, diameter, grades, rebarType, baseLine, hookDiameter, startRotationAngle, endRotationAngle)
    {
        this.m_lengthOfHook = lengthOfHook;
    }
    public override CurveVector CreateGuideLineOfRebar()
    {
        ComplexStringElement retComplexString = new(Session.Instance.GetActiveDgnModel(), null);

        #region 基线除去弯钩部分,剩余曲线
        var baseCurveData = CulvertHelpers.GetElementsByStartAndEndFractionFromCurveVector(this.BaseLine, (this.HookDiameter + this.Diameter) * 0.5);

        #endregion

        #region 起点弯钩
        List<Element> startHookLines = this.CreateStartHookLine((DPoint3d)baseCurveData.startPoint!, (DVector3d)baseCurveData.startTangentVector!);
        #endregion

        #region 终点弯钩
        List<Element> endHookLine = this.CreateEndHookLine((DPoint3d)baseCurveData.endPoint!, (DVector3d)baseCurveData.endTangentVector!);
        #endregion
        retComplexString.AddComponentElement(startHookLines[0]);
        retComplexString.AddComponentElement(startHookLines[1]);
        for (int i = 0; i < baseCurveData.curveElements.Count; i++)
        {
            retComplexString.AddComponentElement(baseCurveData.curveElements[i]);
        }
        retComplexString.AddComponentElement(endHookLine[0]);
        retComplexString.AddComponentElement(endHookLine[1]);
        CurveVector retCurves = CurvePathQuery.ElementToCurveVector(retComplexString);
        return retCurves;
    }

    public override List<(string standardName, string standValue)> CreateStandardECProperty()
    {
        string rebarJsonFilePath =
            System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) +
            @"\rebarConfig.json";
        List<(string standardName, string standValue)> ret = new();
        var cv = this.CreateGuideLineOfRebar();
        var rebarVolume = cv.SumOfLengths() / GeneralHelpers.UorToMeters * Math.PI *
                          Math.Pow(0.5 * this.Diameter * 0.001, 2);
        var rebarLength = cv.SumOfLengths() / GeneralHelpers.UorToMeters;
        ret.Add(("componentName", this._constructingEntity.ToString()));
        ret.Add(("rebarGroup", this.RebarGroupNumber));
        ret.Add(("rebarDiameter", this.Diameter.ToString()));
        ret.Add(("rebarVolume", rebarVolume.ToString()));
        ret.Add(("rebarType", this.RebarType == RebarType.Ribbed ? "带肋" : "光圆"));
        ret.Add(("rebarGrade", this.Grades));
        ret.Add(("rebarLength", rebarLength.ToString()));
        ret.Add(("weightPerMeter", GeneralHelpers.GetWeightPerMeterOfRebar(this.Grades, this.Diameter, rebarJsonFilePath).ToString()));
        ret.Add(("rebarHookLength", this.m_lengthOfHook.ToString()));
        ret.Add(("rebarHookDiameter", this.HookDiameter.ToString()));
        return ret;
    }
    private List<Element> CreateStartHookLine(DPoint3d uorLocate, DVector3d pathDir)
    {
        List<Element> elements = new List<Element>();
        double radius = (this.HookDiameter + this.Diameter) * 0.5 * 0.001 * GeneralHelpers.UorToMeters;
        double hookLength = this.m_lengthOfHook * 0.01 * GeneralHelpers.UorToMeters;
        DPoint3d centerPoint = new(radius, 0, 0);

        #region 弯钩直线部分
        //弯钩直线段长度
        double hookStraightLineLength = hookLength - radius / Math.Atan(Math.PI / 8);
        DVector3d vectorLine = DVector3d.UnitX.RotateXY(new Angle() { Degrees = 45 }); //直线段向量
        DVector3d vector = DVector3d.UnitX.RotateXY(new Angle() { Degrees = -45 });
        DPoint3d endPointOfStraightLine = centerPoint + vector * radius;
        DPoint3d startPointOfStraightLine = endPointOfStraightLine + vectorLine * hookStraightLineLength;
        LineElement lineElement = new LineElement(Session.Instance.GetActiveDgnModel(), null,
           new DSegment3d(startPointOfStraightLine, endPointOfStraightLine));
        var tempLine = CulvertHelpers.TransformElementRoate90ByXaxis(lineElement, 90);
        var rotateTempLine = CulvertHelpers.TransformElementRoate90ByZaxis(tempLine, -this.StartRotationAngle);
        var hookLine = CulvertHelpers.TransformElementNormaltoPath(rotateTempLine, uorLocate, pathDir);
        //hookLine.AddToModel();
        elements.Add(hookLine);
        #endregion

        #region 弯钩弧部分
        ArcElement arcElement = new ArcElement(Session.Instance.GetActiveDgnModel(), null,
            centerPoint, radius, radius, DMatrix3d.Identity, 7.0 / 4.0 * Math.PI, -Math.PI * 0.75);
        var tempArc = CulvertHelpers.TransformElementRoate90ByXaxis(arcElement, 90);
        var rotateTempArc = CulvertHelpers.TransformElementRoate90ByZaxis(tempArc, -this.StartRotationAngle);
        var hookArc = CulvertHelpers.TransformElementNormaltoPath(rotateTempArc, uorLocate, pathDir);
        //hookArc.AddToModel();
        elements.Add(hookArc);

        #endregion
        return elements;
    }

    private List<Element> CreateEndHookLine(DPoint3d uorLocate, DVector3d pathDir)
    {
        List<Element> elements = new List<Element>();
        double radius = (this.HookDiameter + this.Diameter) * 0.5 * 0.001 * GeneralHelpers.UorToMeters;
        double hookLength = this.m_lengthOfHook * 0.01 * GeneralHelpers.UorToMeters;
        DPoint3d centerPoint = new(radius, 0, 0);

        #region 弯钩弧部分
        ArcElement arcElement = new ArcElement(Session.Instance.GetActiveDgnModel(), null,
           centerPoint, radius, radius, DMatrix3d.Identity, Math.PI, Math.PI * 0.75);
        var tempArc = CulvertHelpers.TransformElementRoate90ByXaxis(arcElement, -90);
        var rotateTempArc = CulvertHelpers.TransformElementRoate90ByZaxis(tempArc, -this.EndRotationAngle);
        var hookArc = CulvertHelpers.TransformElementNormaltoPath(rotateTempArc, uorLocate, pathDir);
        //hookArc.AddToModel();
        elements.Add(hookArc);
        #endregion

        #region 弯钩直线部分
        double hookStraightLineLength = hookLength - radius / Math.Atan(Math.PI / 8);
        DVector3d vectorLine = DVector3d.UnitX.RotateXY(new Angle() { Degrees = 45 }); //直线段向量
        DVector3d vector = DVector3d.UnitX.RotateXY(new Angle() { Degrees = -45 });
        DPoint3d startPointOfStraightLine = centerPoint + vector * radius;
        DPoint3d endPointOfStraightLine = startPointOfStraightLine + vectorLine * hookStraightLineLength;
        LineElement lineElement = new LineElement(Session.Instance.GetActiveDgnModel(), null,
          new DSegment3d(startPointOfStraightLine, endPointOfStraightLine));
        var tempLine = CulvertHelpers.TransformElementRoate90ByXaxis(lineElement, -90);
        var rotateTempLine = CulvertHelpers.TransformElementRoate90ByZaxis(tempLine, -this.EndRotationAngle);
        var hookLine = CulvertHelpers.TransformElementNormaltoPath(rotateTempLine, uorLocate, pathDir);
        //hookLine.AddToModel();
        elements.Add(hookLine);
        #endregion
        return elements;
    }

}
